package br.com.mkmts.dao.jpa.cadastro;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.NoResultException;

import org.springframework.stereotype.Repository;

import br.com.mkmts.dao.cadastro.ProdutoDao;
import br.com.mkmts.dao.jpa.JpaGenericDao;
import br.com.mkmts.dto.ProdutoDTO;
import br.com.mkmts.model.produtos.ProdutoEntity;
import br.com.mkmts.utils.MkmtsUtil;

@Repository
public class ProdutoDaoImpl extends JpaGenericDao<ProdutoEntity, Long> implements ProdutoDao{

	final String SELECTQUERY_PRODUTO_DISP_QTDE = 
			"SELECT p" +
			", COALESCE(e.disponivel,false)" +
			", COALESCE(e.qtdeProdutoEmEstoque,0) " +
			"FROM EstoqueEntity e " +
			"RIGHT JOIN e.codProduto p ";
	
	@Override
	public List<ProdutoDTO>findCatalogoByFiltros(Long codMk, String nomeProduto, List<Integer> codCategoria, boolean estoqueFiltro) {
		boolean flag = false;
		StringBuilder query = new StringBuilder();
		
		
		if(estoqueFiltro){
			query.append(SELECTQUERY_PRODUTO_DISP_QTDE+_ESPACE+"WHERE p.codProduto = e.codProduto");
			query.append(_ESPACE);
			flag = true;
		}else{
			query.append(SELECTQUERY_PRODUTO_DISP_QTDE);
			query.append(_ESPACE);
		}
		
		if(codMk > 0){
			if(flag){
				query.append("AND p.codProduto = "+codMk+"");
				query.append(_ESPACE);
			}else{
				query.append("WHERE p.codProduto = "+codMk+"");
				query.append(_ESPACE);
				flag = true;
			}
		}

		if(!nomeProduto.equals("")){
			if(flag){
				query.append("AND p.descProduto LIKE '%"+nomeProduto+"%'");
				query.append(_ESPACE);
			}else{
				query.append("WHERE p.descProduto LIKE '%"+nomeProduto+"%'");
				query.append(_ESPACE);
				flag = true;
			}
		}	
		
		if(!codCategoria.isEmpty()){
			String c = codCategoria.toString().replace("[", "").replace("]", "");
			
			if(flag){
				query.append("AND p.codCategoria IN("+c+")");
				query.append(_ESPACE);
				
			}else{
				query.append("WHERE p.codCategoria IN("+c+")");
				query.append(_ESPACE);
				flag = true;
			}
		}	
		
		query.append(ORDER_BY);
		
		List<Object[]> listaRetornada = (List<Object[]>) getEntityManager().createQuery(query.toString(), Object[].class).getResultList();
				
		return carregaOcorrencias(listaRetornada);
	}
	
	@Override
	public List<ProdutoDTO> buscarItensExistentesNoCatalogo(List<String> array) {
		String c = array.toString().replace("[", "").replace("]", "");
		StringBuilder builder = new StringBuilder();
		builder.append(SELECT);
		builder.append(_ESPACE);
		builder.append("WHERE p.codProduto IN ("+c+")");
		
		return carregaOcorrenciasCatalogo(getEntityManager().createQuery(builder.toString(), ProdutoEntity.class).getResultList());
	}
	
	@Override
	public boolean existsProduct(Long id) {
		StringBuilder builder = new StringBuilder();
		builder.append(SELECT);
		builder.append(_ESPACE);
		builder.append("WHERE p.codProduto = "+id);
		builder.append(_ESPACE);
		builder.append(ORDER_BY);
		
		try{
			if(getEntityManager().createQuery(builder.toString()).getSingleResult() == null){
				return false;
			}
			return true;
		}catch(NoResultException nre){
			return false;
		}
	}
	
	
	private List<ProdutoDTO> carregaOcorrencias(List<Object[]>listaRetornada){
		List<ProdutoDTO>listaSaida = new ArrayList<ProdutoDTO>();
		if(!MkmtsUtil.verificaListNullOrEmpty(listaRetornada)){
			for (int i = 0; i < listaRetornada.size(); i++) {
				ProdutoDTO dto = new ProdutoDTO();
				dto.setCodProduto((ProdutoEntity) listaRetornada.get(i)[0]);
				dto.setDisponivel((Boolean) listaRetornada.get(i)[1]);
				dto.setQuantidadeEmEstoque((Integer) listaRetornada.get(i)[2]);
				listaSaida.add(dto);
			}
		}
		return listaSaida;
	}
	private List<ProdutoDTO> carregaOcorrenciasCatalogo(List<ProdutoEntity>listaRetornada){
		List<ProdutoDTO>listaSaida = new ArrayList<ProdutoDTO>();
		if(!MkmtsUtil.verificaListNullOrEmpty(listaRetornada)){
			for (int i = 0; i < listaRetornada.size(); i++) {
				ProdutoDTO dto = new ProdutoDTO();
				dto.setCodProduto(listaRetornada.get(i));
				listaSaida.add(dto);
			}
		}
		return listaSaida;
	}
	
}
